// 用户交互响应性能优化服务

export interface InteractionMetrics {
  type: 'click' | 'input' | 'scroll' | 'hover' | 'keyboard' | 'touch';
  startTime: number;
  endTime?: number;
  duration?: number;
  target: string;
  isBlocked: boolean;
  delay: number;
}

export interface ThrottleConfig {
  scroll: number;
  resize: number;
  mousemove: number;
  input: number;
}

export interface DebounceConfig {
  search: number;
  autoSave: number;
  validation: number;
  api: number;
}

export interface ResponsivenessConfig {
  targetResponseTime: number; // ms
  throttleConfig: ThrottleConfig;
  debounceConfig: DebounceConfig;
  enableVirtualization: boolean;
  enableRequestIdleCallback: boolean;
  batchUpdates: boolean;
}

/**
 * 用户交互响应性能优化服务
 */
export class ResponsivenessOptimizationService {
  private config: ResponsivenessConfig;
  private interactionHistory: InteractionMetrics[] = [];
  private throttledFunctions = new Map<string, (...args: any[]) => void>();
  private debouncedFunctions = new Map<string, (...args: any[]) => void>();
  private rafCallbacks = new Set<number>();
  private updateQueue: Array<() => void> = [];
  private isProcessingUpdates = false;

  constructor(config: ResponsivenessConfig) {
    this.config = config;
    this.initializeOptimizations();
  }

  /**
   * 初始化优化功能
   */
  private initializeOptimizations(): void {
    console.log('[响应性能] 初始化用户交互优化');

    // 监听长任务
    this.observeLongTasks();

    // 监听输入延迟
    this.observeInputDelay();

    // 设置更新批处理
    if (this.config.batchUpdates) {
      this.setupUpdateBatching();
    }
  }

  /**
   * 监听长任务
   */
  private observeLongTasks(): void {
    try {
      if ('PerformanceObserver' in window) {
        const observer = new PerformanceObserver((list) => {
          for (const entry of list.getEntries()) {
            if (entry.duration > 50) { // 超过50ms的任务
              console.warn(`[响应性能] 检测到长任务: ${entry.duration.toFixed(2)}ms`, entry);
              this.recordInteraction({
                type: 'keyboard',
                startTime: entry.startTime,
                endTime: entry.startTime + entry.duration,
                duration: entry.duration,
                target: 'long-task',
                isBlocked: true,
                delay: entry.duration
              });
            }
          }
        });

        observer.observe({ entryTypes: ['longtask'] });
      }
    } catch (error) {
      console.error('[响应性能] 长任务监听器初始化失败:', error);
    }
  }

  /**
   * 监听输入延迟
   */
  private observeInputDelay(): void {
    try {
      if ('PerformanceObserver' in window) {
        const observer = new PerformanceObserver((list) => {
          for (const entry of list.getEntries()) {
            if (entry.processingStart && entry.startTime) {
              const delay = entry.processingStart - entry.startTime;
              if (delay > this.config.targetResponseTime) {
                console.warn(`[响应性能] 输入延迟过高: ${delay.toFixed(2)}ms`);
              }
              
              this.recordInteraction({
                type: 'input',
                startTime: entry.startTime,
                endTime: entry.processingStart,
                duration: delay,
                target: entry.name || 'unknown',
                isBlocked: delay > this.config.targetResponseTime,
                delay
              });
            }
          }
        });

        observer.observe({ entryTypes: ['first-input'] });
      }
    } catch (error) {
      console.error('[响应性能] 输入延迟监听器初始化失败:', error);
    }
  }

  /**
   * 设置更新批处理
   */
  private setupUpdateBatching(): void {
    // 使用 MessageChannel 进行批处理调度
    const channel = new MessageChannel();
    channel.port2.onmessage = () => {
      this.flushUpdates();
    };

    this.scheduleUpdate = () => {
      channel.port1.postMessage(null);
    };
  }

  private scheduleUpdate: (() => void) | undefined;

  /**
   * 节流函数
   */
  throttle<T extends (...args: any[]) => any>(
    func: T,
    wait: number,
    key?: string
  ): T {
    if (key && this.throttledFunctions.has(key)) {
      return this.throttledFunctions.get(key) as T;
    }

    let lastTime = 0;
    let timeout: NodeJS.Timeout | null = null;

    const throttled = (...args: any[]) => {
      const now = Date.now();
      
      if (now - lastTime >= wait) {
        lastTime = now;
        func.apply(this, args);
      } else if (!timeout) {
        timeout = setTimeout(() => {
          lastTime = Date.now();
          timeout = null;
          func.apply(this, args);
        }, wait - (now - lastTime));
      }
    };

    if (key) {
      this.throttledFunctions.set(key, throttled);
    }

    return throttled as T;
  }

  /**
   * 防抖函数
   */
  debounce<T extends (...args: any[]) => any>(
    func: T,
    wait: number,
    key?: string
  ): T {
    if (key && this.debouncedFunctions.has(key)) {
      return this.debouncedFunctions.get(key) as T;
    }

    let timeout: NodeJS.Timeout | null = null;

    const debounced = (...args: any[]) => {
      if (timeout) {
        clearTimeout(timeout);
      }
      
      timeout = setTimeout(() => {
        func.apply(this, args);
      }, wait);
    };

    if (key) {
      this.debouncedFunctions.set(key, debounced);
    }

    return debounced as T;
  }

  /**
   * 使用 RAF 优化动画
   */
  scheduleAnimation(callback: () => void): number {
    const rafId = requestAnimationFrame(() => {
      this.rafCallbacks.delete(rafId);
      callback();
    });
    
    this.rafCallbacks.add(rafId);
    return rafId;
  }

  /**
   * 取消动画
   */
  cancelAnimation(rafId: number): void {
    if (this.rafCallbacks.has(rafId)) {
      cancelAnimationFrame(rafId);
      this.rafCallbacks.delete(rafId);
    }
  }

  /**
   * 批量更新DOM
   */
  batchUpdate(updateFn: () => void): void {
    if (!this.config.batchUpdates) {
      updateFn();
      return;
    }

    this.updateQueue.push(updateFn);
    
    if (!this.isProcessingUpdates && this.scheduleUpdate) {
      this.scheduleUpdate();
    }
  }

  /**
   * 刷新更新队列
   */
  private flushUpdates(): void {
    if (this.isProcessingUpdates || this.updateQueue.length === 0) {
      return;
    }

    this.isProcessingUpdates = true;
    const updates = [...this.updateQueue];
    this.updateQueue = [];

    try {
      // 批量执行所有更新
      updates.forEach(update => {
        try {
          update();
        } catch (error) {
          console.error('[响应性能] 批量更新失败:', error);
        }
      });
    } finally {
      this.isProcessingUpdates = false;
    }
  }

  /**
   * 空闲时执行任务
   */
  runWhenIdle(callback: () => void, timeout: number = 5000): void {
    if (!this.config.enableRequestIdleCallback || !('requestIdleCallback' in window)) {
      // 降级到 setTimeout
      setTimeout(callback, 0);
      return;
    }

    requestIdleCallback(callback, { timeout });
  }

  /**
   * 优化滚动性能
   */
  optimizeScrollHandler(element: Element, handler: (event: Event) => void): () => void {
    const throttledHandler = this.throttle(
      handler,
      this.config.throttleConfig.scroll,
      `scroll-${element.tagName}-${Date.now()}`
    );

    element.addEventListener('scroll', throttledHandler, { passive: true });

    return () => {
      element.removeEventListener('scroll', throttledHandler);
    };
  }

  /**
   * 优化输入性能
   */
  optimizeInputHandler(
    element: HTMLInputElement,
    handler: (value: string) => void,
    immediate: boolean = false
  ): () => void {
    const processInput = immediate ? 
      this.throttle(handler, this.config.throttleConfig.input, `input-${element.id}`) :
      this.debounce(handler, this.config.debounceConfig.search, `input-${element.id}`);

    const eventHandler = (event: Event) => {
      const target = event.target as HTMLInputElement;
      processInput(target.value);
    };

    element.addEventListener('input', eventHandler);

    return () => {
      element.removeEventListener('input', eventHandler);
    };
  }

  /**
   * 优化鼠标移动处理
   */
  optimizeMouseMoveHandler(element: Element, handler: (event: Event) => void): () => void {
    const throttledHandler = this.throttle(
      handler,
      this.config.throttleConfig.mousemove,
      `mousemove-${element.tagName}-${Date.now()}`
    );

    element.addEventListener('mousemove', throttledHandler, { passive: true });

    return () => {
      element.removeEventListener('mousemove', throttledHandler);
    };
  }

  /**
   * 分时执行大量任务
   */
  async executeInChunks<T>(
    items: T[],
    processor: (item: T, index: number) => void,
    chunkSize: number = 100,
    delay: number = 5
  ): Promise<void> {
    for (let i = 0; i < items.length; i += chunkSize) {
      const chunk = items.slice(i, i + chunkSize);
      
      // 处理当前块
      chunk.forEach((item, chunkIndex) => {
        processor(item, i + chunkIndex);
      });

      // 让出控制权
      if (i + chunkSize < items.length) {
        await new Promise(resolve => setTimeout(resolve, delay));
      }
    }
  }

  /**
   * 记录交互指标
   */
  private recordInteraction(metrics: InteractionMetrics): void {
    this.interactionHistory.push(metrics);
    
    // 限制历史记录长度
    if (this.interactionHistory.length > 1000) {
      this.interactionHistory = this.interactionHistory.slice(-500);
    }

    // 记录慢交互
    if (metrics.delay > this.config.targetResponseTime) {
      console.warn(`[响应性能] 慢交互检测: ${metrics.type} - ${metrics.delay.toFixed(2)}ms`);
    }
  }

  /**
   * 手动记录交互
   */
  recordUserInteraction(
    type: InteractionMetrics['type'],
    target: string,
    startTime?: number
  ): (endTime?: number) => void {
    const start = startTime || performance.now();
    
    return (endTime?: number) => {
      const end = endTime || performance.now();
      const duration = end - start;
      
      this.recordInteraction({
        type,
        startTime: start,
        endTime: end,
        duration,
        target,
        isBlocked: duration > this.config.targetResponseTime,
        delay: duration
      });
    };
  }

  /**
   * 获取性能统计
   */
  getPerformanceStats(): {
    totalInteractions: number;
    averageResponseTime: number;
    slowInteractions: number;
    slowInteractionRate: number;
    interactionsByType: { [key: string]: number };
    worstInteractions: InteractionMetrics[];
  } {
    const total = this.interactionHistory.length;
    const slowInteractions = this.interactionHistory.filter(
      i => i.delay > this.config.targetResponseTime
    );

    const averageResponseTime = total > 0 ?
      this.interactionHistory.reduce((sum, i) => sum + i.delay, 0) / total : 0;

    const interactionsByType = this.interactionHistory.reduce((acc, i) => {
      acc[i.type] = (acc[i.type] || 0) + 1;
      return acc;
    }, {} as { [key: string]: number });

    const worstInteractions = this.interactionHistory
      .sort((a, b) => b.delay - a.delay)
      .slice(0, 10);

    return {
      totalInteractions: total,
      averageResponseTime,
      slowInteractions: slowInteractions.length,
      slowInteractionRate: total > 0 ? slowInteractions.length / total : 0,
      interactionsByType,
      worstInteractions
    };
  }

  /**
   * 优化建议
   */
  getOptimizationSuggestions(): string[] {
    const stats = this.getPerformanceStats();
    const suggestions: string[] = [];

    if (stats.slowInteractionRate > 0.1) {
      suggestions.push('慢交互比例较高，建议优化事件处理器');
    }

    if (stats.averageResponseTime > this.config.targetResponseTime) {
      suggestions.push('平均响应时间超标，建议使用防抖和节流');
    }

    if (stats.interactionsByType.scroll > stats.totalInteractions * 0.3) {
      suggestions.push('滚动事件频繁，建议优化滚动处理器');
    }

    if (stats.interactionsByType.input > stats.totalInteractions * 0.3) {
      suggestions.push('输入事件频繁，建议使用防抖处理');
    }

    if (suggestions.length === 0) {
      suggestions.push('用户交互响应性能良好');
    }

    return suggestions;
  }

  /**
   * 生成性能报告
   */
  generatePerformanceReport(): {
    stats: ReturnType<ResponsivenessOptimizationService['getPerformanceStats']>;
    suggestions: string[];
    score: number;
    config: ResponsivenessConfig;
  } {
    const stats = this.getPerformanceStats();
    const suggestions = this.getOptimizationSuggestions();
    const score = this.calculatePerformanceScore(stats);

    return {
      stats,
      suggestions,
      score,
      config: this.config
    };
  }

  /**
   * 计算性能分数
   */
  private calculatePerformanceScore(stats: ReturnType<ResponsivenessOptimizationService['getPerformanceStats']>): number {
    let score = 100;

    // 慢交互比例扣分
    score -= stats.slowInteractionRate * 50;

    // 平均响应时间扣分
    if (stats.averageResponseTime > this.config.targetResponseTime) {
      const ratio = stats.averageResponseTime / this.config.targetResponseTime;
      score -= Math.min(30, (ratio - 1) * 30);
    }

    return Math.max(0, Math.round(score));
  }

  /**
   * 清理资源
   */
  cleanup(): void {
    // 清理所有RAF回调
    this.rafCallbacks.forEach(id => cancelAnimationFrame(id));
    this.rafCallbacks.clear();

    // 清理函数缓存
    this.throttledFunctions.clear();
    this.debouncedFunctions.clear();

    // 清理更新队列
    this.updateQueue = [];
    this.isProcessingUpdates = false;

    console.log('[响应性能] 资源清理完成');
  }
}

// 默认配置
export const defaultResponsivenessConfig: ResponsivenessConfig = {
  targetResponseTime: 100, // 100ms
  throttleConfig: {
    scroll: 16, // ~60fps
    resize: 100,
    mousemove: 16,
    input: 50
  },
  debounceConfig: {
    search: 300,
    autoSave: 1000,
    validation: 500,
    api: 300
  },
  enableVirtualization: true,
  enableRequestIdleCallback: true,
  batchUpdates: true
};